<!DOCTYPE html>
<html lang="zh-cn">
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">




<title>响应式Web开发 | Miles`s</title>

<link rel="stylesheet" href="https://mada.gitee.io/notes//css/styles.css">

<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.2.0/css/all.css" 
integrity="sha384-hWVjflwFxL6sNzntih27bfxkr27PmbbK/iSvJ+a4+0owXq79v+lsFkW54bOGbiDQ" crossorigin="anonymous">
<script src="https://code.jquery.com/jquery-3.3.1.js" integrity="sha256-2Kok7MbOyxpgUVvAk/HJ2jigOSYS2auK4Pfzbm7uH60=" crossorigin="anonymous"></script>


<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/zenburn.min.css" crossorigin="anonymous" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/highlight.min.js" integrity="sha256-/BfiIkHlHoVihZdc6TFuj7MmJ0TWcWsMXkeDFwhi0zw=" crossorigin="anonymous"></script>
<script>hljs.initHighlightingOnLoad();</script>
<script src="https://mada.gitee.io/notes//js/highlight.js"></script>






<div class="container">
    <nav class="navbar level">
      <div class="navbar-brand">
          <a class="nav-item" href="https://mada.gitee.io/notes/"><h1 class="title is-3">Miles`s</h1></a>
      </div>           
      <div class="navbar-menu has-text-centered is-active">
          <div class="navbar-end is-centered">
              
           </div>
      </div>
    </nav>
  </div>
<div class="container">
  <h2 class="subtitle is-6">November 14, 2016</h2>
  <h1 class="subtitle is-size-4-mobile is-size-3-desktop">响应式Web开发</h1>
  <div class="content">
    

<h2 id="视觉稿">视觉稿</h2>

<p>视觉稿：PSD，效果图等。</p>

<ol>
<li>选取一款手机的屏幕宽高作为基准（5s，6s等）</li>
<li>对于retina屏幕（dpr＝2），为了达到高清效果，视觉稿的画布大小会是基准的2倍。</li>
</ol>

<h2 id="术语">术语</h2>

<p><strong>物理像素(physical pixel)</strong></p>

<p>一个物理像素是显示器（手机屏幕）上最小的物理显示单元，在操作系统的调度下，每一个设备像素都有自己的颜色值和高度值。</p>

<p><strong>设备独立像素（density-independent pixel）</strong></p>

<p>设备独立像素（也叫密度无关像素），可以认为是计算机坐标系统中的一个点，这个点代表一个可以由程序使用的虚拟像素（比如：css像素），然后由相关系统转换为物理像素。</p>

<p><strong>设备像素比（device pixel ratio）</strong></p>

<p>定义了物理像素和设备独立像素的对应关系，它的值可以按如下公式得到：</p>

<p><code>设备像素比 ＝ 物理像素 / 设备独立像素  // 在某一方向上，x方向或者y方向</code></p>

<p>在JavaScript中，可以通过<strong>window.devicePixelRatio</strong>获取当前设备的dpr。</p>

<p>在CSS中，可以通过<strong>-webkit-device-pixel-ratio</strong>,<strong>-webkit-min-device-pixel-ratio</strong>和<strong>-webkit-max-device-pixel-ratio</strong>进行媒体查询，对不同dpr设备，做一些样式适配（这里只针对webkit内核的浏览器和webview）</p>

<p>以<strong>iphone6</strong>为例：</p>

<ol>
<li>设备高度为<strong>275*667</strong>，可以理解为设备独立像素（或css像素）。</li>
<li>dpr为2，根据上面的计算公式，其物理像素就应该是<strong>x2</strong>，为<strong>750*1334</strong></li>
</ol>

<p><img src="./pixel.jpg" alt="pixel" /></p>

<p>对于CSS样式：</p>

<pre><code class="language-css">width: 2px;
height: 2px;
</code></pre>

<p>在不同的屏幕上，CSS像素所呈现的大小（物理尺寸）是一致的，不同的是1个CSS像素所对应的物理像素个数是不一致的。</p>

<ul>
<li>在普通屏幕下，1个CSS像素对应一个物理像素（1:1）。</li>
<li>在retina屏幕下，ratio为2，1个CSS像素对应4个物理像素（1:4）.</li>
</ul>

<p><strong>位图像素</strong></p>

<p>一个位图像素是删格图像最小的数据单元。每一个位图像素都包含着一些自身的显示信息（如：显示位置，颜色值，透明度）。</p>

<p>理论上，1个位图像素对应于1个物理像素，图片才能得到完美清晰的展示。</p>

<p>在普通屏幕下是没有问题的，但是在retina屏幕下就会出现位图像素点不够，从而导致图片模糊的情况。</p>

<p><img src="bit-image.jpg" alt="bit image" /></p>

<p>如上图：对于dpr＝2点retina屏幕而言，1个位图像素对应于4个物理像素，由于单个位图像素不可以再进一步分割，所以只能就近取色，从而导致图片模糊。</p>

<p>所以，对于图片高清问题，比较好的方案就是<strong>两倍图片</strong>(@2x)</p>

<p>同时，这里会产生另外一个问题，如果在普通屏幕下，也用了<strong>两倍图片</strong>，会怎样呢？</p>

<p>很明显，在普通屏幕下，就会出现一个物理像素点对应4个位图像素点，所以它的颜色也只能通过一定的算法（dawnsampling），肉眼看上去虽然图像不会模糊，但是会觉得图片缺少了一些锐度，活着是有点色差（但是是可以接受的）。</p>

<p><img src="image-2xto1x.jpg" alt="" /></p>

<p><strong>retina下，图片高清问题</strong></p>

<p>设置图片的容器缩小50%。</p>

<p>如，图片大小， 400*600</p>

<p><strong>img标签：</strong></p>

<pre><code class="language-css">width: 200px;
height: 300px;
</code></pre>

<p><strong>背景图片：</strong></p>

<pre><code class="language-css">width: 200px;
height: 300px;
background-image: url(img@2x.jpg);
background-size: 200px 300px; // background-size:contain;
</code></pre>

<p>最好的办法是，不同的dpr，加载不同尺寸的图片。
可以通过CSS媒体查询，也可以通过JavaScript条件判断。</p>

<p><strong>在retina下，border:1px问题</strong></p>

<p>看图说话：</p>

<p><img src="./one-px.jpg" alt="" /></p>

<p>上图中，对于一条<strong>1px</strong>宽的直线，它们在屏幕上的物理尺寸(灰色区域)的确是相同的，不同的其实是屏幕上最小的物理显示单元，即物理像素，所以对于一条直线，iphone5它能显示的最小宽度其实是图中的红线圈出来的灰色区域，用css来表示，理论上说是<strong>0.5px</strong>。</p>

<p>所以，设计师想要的retina下border: 1px;，其实就是1物理像素宽，对于css而言，可以认为是border: 0.5px;，这是retina下(dpr=2)下能显示的最小单位。</p>

<p>然而，无奈并不是所有手机浏览器都能识别border: 0.5px;，ios7以下，android等其他系统里，0.5px会被当成为0px处理，那么如何实现这0.5px呢？</p>

<p>解决方法：</p>

<ol>
<li>使用CSS <strong>transfrom：scale(.5)</strong>. 然而这样的写法非常繁琐。</li>
<li>设置<strong>meta</strong>标签
<code>&lt;meta name=&quot;viewport&quot; content=&quot;width=640,initial-scale=0.5,maximum-scale=0.5, minimum-scale=0.5,user-scalable=no&quot;&gt;</code>
<br /></li>
</ol>

<p>这样，页面中的所有的border: 1px都将缩小0.5，从而达到border: 0.5px;的效果。</p>

<p>效果图（<a href="http://div.io/user/lovesueee">Lovesueee</a> 的效果图）
<img src="./px1-image.jpg" alt="" /></p>

<p>然而这样做会带来一些问题：</p>

<ol>
<li>字体大小会会被缩放</li>
<li>页面布局会被缩放（如：div的宽高）</li>
</ol>

<h2 id="多屏适配布局问题">多屏适配布局问题</h2>

<p>移动端布局，为了适配各种大屏手机，目前最好用的方案莫过于使用相对单位<strong>rem</strong>.</p>

<p>基于rem的原理，完美要做的就是：针对不同的手机<strong>屏幕尺寸</strong>和dpr动态改变节点html的<strong>font-size</strong>大小（基准值）。</p>

<p>rem计算公式：</p>

<p><code>rem = document.documentElement.clientWidth * dpr /10</code></p>

<p>说明：</p>

<ol>
<li>乘以dpr，是因为页面有可能为了实现<strong>1px border</strong>页面会缩放(scale)1/dpr倍(如果没有，dpr=1).</li>
<li>除以10，是为了取整，方便计算(理论上可以是任何值)</li>
</ol>

<h1 id="资料">资料</h1>

<p><a href="http://div.io/topic/1092">移动端高清，多屏适配方案</a></p>

  </div>
</div>
<div class="container has-text-centered">
    
</div>

<div class="container has-text-centered">
  
</div>
<section class="section">
  <div class="container has-text-centered">
    <p></p>
  </div>
</section>


